﻿using ECMS.AppService.Interfaces;
using ECMS.AppService.Model.Models;
using ECMS.AppService.Model.Responses;
using ECMS.AppService.Model.Requests;
using ECMS.Domain.Models;
using ECMS.Infrastructure.ClientData;
using ECMS.Infrastructure.Domain;
using ECMS.Infrastructure.Extensions;
using ECMS.Infrastructure.Provider.Implements;
using Microsoft.EntityFrameworkCore;
using QuestionBank.Infrastructure.Helper;
using System;
using System.Linq;
using System.Threading.Tasks;

namespace ECMS.AppService.Implements
{
    public partial class UserService
    {
        public async Task<ApiResult<SaveResponse>> SaveAsync(UserModel model)
        {
            var response = new ApiResult<SaveResponse>
            {
                StatusCode = 200
            };
            try
            {
                if (model == null)
                    throw new ArgumentNullException(nameof(model));
                User entity;
                if (model.Guid == null)
                {
                    // 用户名唯一检查
                    if (Query().Any(p => p.LoginName == model.LoginName))
                    {
                        response.Message = "登录已存在,请更改.";
                        return response;
                    }
                    // 手机号唯一检查
                    if (Query().Any(p => p.Mobile == model.Mobile))
                    {
                        response.Message = "手机号已存在,请更改.";
                        return response;
                    }
                    // 电子邮箱唯一检查
                    if (!string.IsNullOrEmpty(model.Email) && Query().Any(p => p.Email == model.Email))
                    {
                        response.Message = "电子邮箱已存在,请更改.";
                        return response;
                    }

                    entity = new User
                    {
                        LoginName = model.LoginName,
                        Password = CryptoHelper.DESEncrypt(model.Password),
                        Mobile = model.Mobile,
                        RealName = model.RealName,
                        Remark = model.Remark,
                        AllowIPAddresses = model.AllowIPAddresses,
                        Email = model.Email,
                        IPLimitEnabled = model.IPLimitEnabled,
                        LockoutEnabled = model.LockoutEnabled,
                        Tel = model.Tel,
                        LockoutEnd = model.LockoutEnd
                    };

                    await _unitofwork.RegisterNewAsync(entity);
                }
                else
                {
                    // 用户名唯一检查
                    if (Query().Any(p => p.LoginName == model.LoginName && p.Guid != model.Guid))
                    {
                        response.Message = "登录已存在,请更改.";
                        return response;
                    }
                    // 手机号唯一检查
                    if (Query().Any(p => p.Mobile == model.Mobile && p.Guid != model.Guid))
                    {
                        response.Message = "手机号已存在,请更改.";
                        return response;
                    }
                    // 电子邮箱唯一检查
                    if (!string.IsNullOrEmpty(model.Email) && Query().Any(p => p.Email == model.Email && p.Guid != model.Guid))
                    {
                        response.Message = "电子邮箱已存在,请更改.";
                        return response;
                    }

                    entity = await Query().Where(p => p.Guid == model.Guid).FirstOrDefaultAsync();
                    if (entity == null)
                    {
                        response.Message = "找不到该用户信息，更新失败.";
                        return response;
                    }
                    entity.LoginName = model.LoginName;
                    if (entity.Password != model.Password)
                        entity.Password = CryptoHelper.DESEncrypt(model.Password);
                    entity.Mobile = model.Mobile;
                    entity.RealName = model.RealName;
                    entity.Remark = model.Remark;
                    entity.AllowIPAddresses = model.AllowIPAddresses;
                    entity.Email = model.Email;
                    entity.IPLimitEnabled = model.IPLimitEnabled;
                    entity.LockoutEnabled = model.LockoutEnabled;
                    entity.Tel = model.Tel;
                    entity.LockoutEnd = model.LockoutEnd;

                    _unitofwork.RegisterDirty(entity);
                }
                var flag = await _unitofwork.CommitAsync();
                response.Success = flag;
                response.Message = flag ? "保存成功." : "保存失败.";

            }
            catch (Exception ex)
            {
                response.Message = ex.Message;
                response.StatusCode = 500;
            }

            return response;
        }

        public async Task<ApiResult<Page<UserResponse>>> GetPagesAsync(GetUserPagesRequest request)
        {
            var response = new ApiResult<Page<UserResponse>>
            {
                StatusCode = 200
            };
            try
            {
                if (request == null)
                    throw new ArgumentNullException(nameof(request));
                var result = await Query()
                    .HasWhere(request.LoginName,p=>p.LoginName.Contains(request.LoginName))
                    .HasWhere(request.RealName, p => p.RealName.Contains(request.RealName))
                    .HasWhere(request.Mobile, p => p.Mobile.Contains(request.Mobile))
                    .OrderByDescending(p => p.Id)
                    .ToPageAsync(request.PageIndex, request.PageSize);

                var flag = result.Items != null && result.Items.Count > 0;
                response.Success = flag;
                response.Message = flag ? "获取成功." : "暂无数据.";

                if (flag)
                {
                    response.Data = result.ToViewPage(p => new UserResponse
                    {
                        LoginName = p.LoginName,
                        Mobile = p.Mobile,
                        Guid = p.Guid,
                        Id = p.Id,
                        Password = p.Password,
                        RealName = p.RealName,
                        Remark = p.Remark,
                        CreateTime = p.CreateTime.ToString("yyyy-MM-dd HH:mm:ss"),
                        AllowIPAddresses = p.AllowIPAddresses,
                        Email = p.Email,
                        IPLimitEnabled = p.IPLimitEnabled,
                        LockoutEnabled = p.LockoutEnabled,
                        Tel = p.Tel,
                        LockoutEnd = p.LockoutEnd
                    });
                }

            }
            catch (Exception ex)
            {
                response.Message = ex.Message;
                response.StatusCode = 500;
            }

            return response;
        }

        public async Task<UserResponse> GetDetailAsync(Guid guid)
        {
            var single = await Query().FirstOrDefaultAsync(p => p.Guid == guid);
            if (single == null)
                return new UserResponse();
            return new UserResponse
            {
                Guid = single.Guid,
                Id = single.Id,
                LoginName = single.LoginName,
                Mobile = single.Mobile,
                Password = single.Password,
                RealName = single.RealName,
                Remark = single.Remark,
                AllowIPAddresses = single.AllowIPAddresses,
                Email = single.Email,
                IPLimitEnabled = single.IPLimitEnabled,
                LockoutEnabled = single.LockoutEnabled,
                Tel = single.Tel,
                LockoutEnd = single.LockoutEnd
            };
        }

        public async Task<ApiResult<string>> DeleteAsync(Guid? guid)
        {
            var response = new ApiResult<string>
            {
                StatusCode = 200
            };
            try
            {
                if (guid == null)
                    throw new ArgumentNullException(nameof(guid));
                // 物理删除
                Delete(p => p.Guid == guid);

                var flag = await _unitofwork.CommitAsync();
                response.Success = flag;
                response.Message = flag ? "移除成功." : "移除失败.";

            }
            catch (Exception ex)
            {
                response.Message = ex.Message;
                response.StatusCode = 500;
            }

            return response;
        }


        public async Task<ApiResult<UserResponse>> LoginAsync(LoginRequest request)
        {
            var response = new ApiResult<UserResponse>();
            try
            {
                // 读取用户信息
                var entity = await Query().FirstOrDefaultAsync(p => p.LoginName == request.LoginName || p.Mobile == request.LoginName || p.Email == request.LoginName);
                if (entity == null)
                {
                    response.Message = "用户不存在.";
                    return response;
                }
                if (entity.Password != CryptoHelper.DESEncrypt(request.Password))
                {
                    response.Message = "用户名或密码错误.";
                    return response;
                }
                if (entity.LockoutEnabled && entity.LockoutEnd > DateTime.Now)
                {
                    response.Message = $"帐号已锁定,于{entity.LockoutEnd.ToString("yyyy-MM-dd HH:mm:ss")}自动解锁.";
                    return response;
                }
                if (entity.IPLimitEnabled && !entity.AllowIPAddresses.Split(',').ToList().Any(p => p == request.LoginIP))
                {
                    response.Message = "该帐号启用了IP限制登录,当前登录IP无效,请联系管理员.";
                    return response;
                }
                if (entity.LockoutEnabled)
                {
                    entity.LockoutEnabled = false;// 帐号解除锁定
                    _unitofwork.RegisterDirty(entity);
                    await _unitofwork.CommitAsync();
                }
                response.Success = true;
                response.Message = "验证成功.";
                response.Data = new UserResponse
                {
                    Guid = entity.Guid,
                    Id = entity.Id,
                    LoginName = entity.LoginName,
                    Mobile = entity.Mobile,
                    RealName = entity.RealName,
                    Remark = entity.Remark
                };
            }
            catch (Exception ex)
            {
                response.Message = ex.Message;
                response.StatusCode = 500;
            }
            return response;
        }
    }
}
